<?php
/*
 * [JINYUN!] (C)2001-2099 Jinyunweb.com
 * This is NOT a freeware, use is subject to license terms
 * $Id: 2017-12-13 03:39:35 apple $
*/
/*
	微信开放平台类，实现微信开放平台接口对接，开放平台类的主要功能，实现公众号的接入。小程序的接入和发布。公众号的接口调用不放在里面
*/
namespace core;
defined('BY_JYA') or exit('error');
class open{
	private $component_appid='';//初始化开放平台信息
	private $component_appsecret='';//初始化开放平台信息
	private $back_url='';//初始化开放平台回调url地址，以上三项需在代码运行前填写
	private $component_access_token='';//开放平台 component_access_token
	private $component_verify_ticket='';
	private $wxapp=array();
	private $wechat=array();
	private $commit_url='https://api.weixin.qq.com/wxa/commit?access_token=';//提交代码接口
	private $submit_url='https://api.weixin.qq.com/wxa/submit_audit?access_token=';//提交审核接口
	private $get_qrcode_url='https://api.weixin.qq.com/wxa/get_qrcode?access_token=';//获取小程序体验二维码
	private $refresh_url='https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=';//刷新 access_token
	public function __construct($wxappid=0,$wechatid=0){
		global $_AR;
		$this->back_wxapp_url=$_AR['siteroot'].'manage/index.php?plugin=core&action=wxapp.list&op=result';
		$this->back_wechat_url=$_AR['siteroot'].'manage/index.php?plugin=core&action=wechat.list&op=result';
		$this->back_bind_url=$_AR['siteroot'].'manage/index.php?plugin=core&action=account.open_fans&op=result';
		$open=core_setting('open');
		if(!$open['appid'] || !$open['secret'] || !$open['ticket']){
			return false;
		}
		$this->component_appid=$open['appid'];
		$this->component_appsecret=$open['secret'];
		$this->component_verify_ticket=$open['ticket'];
		if(!$open['expire'] || $open['expire']<TIMESTAMP){
			//缺少 access_token ，则获取之
			$url='https://api.weixin.qq.com/cgi-bin/component/api_component_token';
			$post=array(
				'component_appid'=>$this->component_appid,
				'component_appsecret'=>$this->component_appsecret,
				'component_verify_ticket'=>$this->component_verify_ticket
			);
			$result=$this->request($url,$post);
			if(!$result['component_access_token']){
				$this->log_error($result,'获取开放平台access_token');
				return false;
			}
			$open['access_token']=$result['component_access_token'];
			$open['expire']=TIMESTAMP+$result['expires_in']-200;
			core_setting('open',$open);
		}
		$this->component_access_token=$open['access_token'];
		$this->get_access_token($wxappid,$wechatid);
	}
	//获取引导授权url
	public function get_sq_url($type,$id=0){
		$pre_auth_code=$this->get_pre_auth_code();
		if($type==3){
			//粉丝绑定
			$backurl=$this->back_bind_url.'&id='.$id;
			$url='https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$this->component_appid.'&pre_auth_code='.$pre_auth_code.'&redirect_uri='.urlencode($backurl);
		}elseif($type==2){
			//小程序
			$backurl=$this->back_wxapp_url.'&id='.$id;
			$url='https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$this->component_appid.'&pre_auth_code='.$pre_auth_code.'&redirect_uri='.urlencode($backurl);
		}else{
			//微信公众号
			$backurl=$this->back_wechat_url.'&id='.$id;
			$url='https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$this->component_appid.'&pre_auth_code='.$pre_auth_code.'&redirect_uri='.urlencode($backurl);
		}
		return $url;
	}
	//获取预授权码
	private function get_pre_auth_code(){
		$url='https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token='.$this->component_access_token;
		$post=array('component_appid'=>$this->component_appid);
		$result=$this->request($url,$post);
		if(!$result['pre_auth_code']){
			$this->log_error($result,'获取开放平台预授权码');
			return false;
		}
		return $result['pre_auth_code'];
	}
	//获取公众号或小程序的详细信息
	public function get_info($appid){
		$url='https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token='.$this->component_access_token;
		$post=array(
			'component_appid'=>$this->component_appid,
			'authorizer_appid'=>$appid
		);
		$result=$this->request($url,$post);
		if(!$result['authorizer_info']){
			$this->log_error($result,'获取公众号或小程序详细信息');
			return false;
		}
		return $result['authorizer_info'];
	}
	//根据 auth_code 获取公众号或小程序的 access_token
	public function get_authorization_info($auth_code){
		$url='https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token='.$this->component_access_token;
		$post=array(
			'component_appid'=>$this->component_appid,
			'authorization_code'=>$auth_code,
		);
		$result=$this->request($url,$post);
		if(!$result['authorization_info']){
			$this->log_error($result,'获取access_token');
			return false;
		}
		return $result['authorization_info'];
	}
	//刷新 access_token
	private function refresh_token(){
		$url=$this->refresh_url.$this->component_access_token;
		if(!$this->authorizer_refresh_token || !$this->authorizer_appid || !$this->component_appid){
			return false;
		}
		$post=array(
			'component_appid'=>$this->component_appid,
			'authorizer_appid'=>$this->authorizer_appid,
			'authorizer_refresh_token'=>$this->authorizer_refresh_token
		);
		$result=$this->request($url,$post);
		if(!$result['authorizer_access_token']){
			$this->log_error($result,'refresh_token');
			return false;
		}
		$update=array(
			'access_token'=>$result['authorizer_access_token'],
			'expire'=>TIMESTAMP+$result['expires_in']-200,
			'refresh_token'=>$result['authorizer_refresh_token']
		);
		if($this->wxapp['id']){
			$this->wxapp['access_token']=$result['authorizer_access_token'];
			$this->wxapp['refresh_token']=$result['authorizer_refresh_token'];
			$this->wxapp['expire']=TIMESTAMP+$result['expires_in']-200;
			pdo_update('core_account_wxapp',$update,array('id'=>$this->wxapp['id']));
		}
		if($this->wechat['id']){
			$this->wechat['access_token']=$result['authorizer_access_token'];
			$this->wechat['refresh_token']=$result['authorizer_refresh_token'];
			$this->wechat['expire']=TIMESTAMP+$result['expires_in']-200;
			pdo_update('core_account_wechat',$update,array('id'=>$this->wechat['id']));
		}
		$access_token=$this->wxapp['access_token']?:$this->wechat['access_token'];
		return $access_token;
	}
	//获取 access_token
	public function get_access_token($wxappid=0,$wechatid=0){
		if($wxappid){
			$wxapp=pdo_get('core_account_wxapp',array('id'=>$wxappid));
			$this->wxapp=$wxapp;
			$this->authorizer_appid=$this->wxapp['appid'];
			$this->authorizer_refresh_token=$this->wxapp['refresh_token'];
			if($this->wxapp['expire']<TIMESTAMP){
				//token 过期
				$access_token = $this->refresh_token();
			}
		}elseif($wechatid){
			$wechat=pdo_get('core_account_wechat',array('id'=>$wechatid));
			$this->wechat=$wechat;
			$this->authorizer_appid=$this->wechat['appid'];
			$this->authorizer_refresh_token=$this->wechat['refresh_token'];
			if($this->wechat['expire']<TIMESTAMP){
				//token 过期
				$access_token = $this->refresh_token();
			}
		}else{
			return false;
		}
		return $access_token;
	}
	//上传小程序
	public function wxapp_sc(){
		global $_AR;
		//提交代码
		$url=$this->commit_url.$this->wxapp['access_token'];
		if(!$this->wxapp['wxapp_id']){
			exi('该小程序尚未选择小程序模版，无法上传！','error');
		}
		$template_id=pdo_getcolumn('core_wxapp',array('id'=>$this->wxapp['wxapp_id']),'template_id');
		if(!$template_id){
			exi('找不到小程序模版id，请联系管理员','error');
		}
		$post=array(
			'template_id'=>$template_id,
			'user_version'=>$this->wxapp['version'],
			'user_desc'=>$this->wxapp['description'],
		);
		$post['ext_json']=ijson_encode(array('extAppid'=>$this->wxapp['appid'],'ext'=>$this->wxapp['ext']));
		$post=ijson_encode($post);
		$result=$this->request($url,$post);
		if($result['errcode']){
			exi('上传失败：'.$result['errcode'].$result['errmsg'],'error');
		}
		return true;
	}
	//提交审核
	public function wxapp_sh(){
		$url='https://api.weixin.qq.com/wxa/get_category?access_token='.$this->wxapp['access_token'];
		$result=$this->request($url);
		$category_list=$result['category_list'];
		$url=$this->submit_url.$this->wxapp['access_token'];
		$item_list=array('0'=>array(
			'address'=>'pages/index/index',
			'tag'=>$this->wxapp['tag'],
			'title'=>$this->wxapp['title'],
			'first_class'=>$category_list['0']['first_class'],
			'second_class'=>$category_list['0']['second_class'],
			'third_class'=>$category_list['0']['third_class'],
			'first_id'=>$category_list['0']['first_id'],
			'second_id'=>$category_list['0']['second_id'],
			'third_id'=>$category_list['0']['third_id'],
		));
		$post=array('item_list'=>$item_list);
		$post=ijson_encode($post);
		$result=$this->request($url,$post);
		if($result['errcode']){
			exi('提交失败：'.$result['errcode'].$result['errmsg'],'error');
		}
		return true;
	}
	public function wxapp_check(){
		if($this->wxapp['status']<2){
			exi('该小程序尚未提交审核，请先提交审核！','error');
		}elseif($this->wxapp['status']==3){
			exi('该小程序已审核成功，可以发布了！','error');
		}elseif($this->wxapp['status']==4){
			exi('该小程序已发布！');
		}
		$auditid=intval($this->wxapp['remark']);
		if(!$auditid){
			exi('该小程序提交审核失败，具体原因为：'.$this->wxapp['remark'].'。无法查看审核状态！','error');
		}
		$url='https://api.weixin.qq.com/wxa/get_auditstatus?access_token='.$this->wxapp['access_token'];
		$post=ijson_encode(array('auditid'=>$auditid));
		$result=$this->request($url,$post);
		if($result['errcode']){
			$data=array('remark'=>$result['errcode'].$result['errmsg']);
			pdo_update('core_account_wxapp',$data,array('id'=>$this->wxapp['id']));
			exi('查看失败：'.$result['errcode'].$result['errmsg'],'error');
		}else{
			if(!$result['status']){
				$data=array('status'=>3,'remark'=>'');
				pdo_update('core_account_wxapp',$data,array('id'=>$this->wxapp['id']));
				exi('审核成功！');
			}elseif($result['status']==1){
				$data=array('remark'=>$result['reason']);
				pdo_update('core_account_wxapp',$data,array('id'=>$this->wxapp['id']));
				exi('审核失败！具体原因：'.$result['reason'],'error');
			}else{
				exi('该小程序还在审核中，请耐心等待！');
			}
		}
	}
	//发布小程序
	public function wxapp_release(){
		if($this->wxapp['status']==4){
			exi('小程序已发布，无需重复发布！','warning');
		}
		if($this->wxapp['status']<3){
			exi('小程序尚未审核成功，无法发布！','warning');
		}
		$url='https://api.weixin.qq.com/wxa/release?access_token='.$this->wxapp['access_token'];
		$post='{}';
		$result=$this->request($url,$post);
		if($result['errcode']){
			$data=array('remark'=>$result['errcode'].$result['errmsg']);
			pdo_update('core_account_wxapp',$data,array('id'=>$this->wxapp['id']));
			exi('发布失败：'.$result['errcode'].$result['errmsg'],'error');
		}else{
			$data=array('status'=>4,'remark'=>'');
			pdo_update('core_account_wxapp',$data,array('id'=>$this->wxapp['id']));
			exi('发布成功！');
		}
	}
	/*
		创建微信开放平台账号
	*/
	public function create_open(){
		$api_url='https://api.weixin.qq.com/cgi-bin/open/create?access_token='.$this->wxapp['access_token'];
		$post=array('appid'=>$this->wxapp['appid']);
		$post=ijson_encode($post);
		$result=$this->request($api_url,$post);
		if($result['errcode']){
			
			exi('绑定失败：'.$result['errcode'].$result['errmsg'],'error');
		}
		$open_appid=$result['open_appid'];
		$open_bind=array(
			'open_appid'=>$open_appid,
			'appid'=>$this->wxapp['appid'],
			'id'=>$this->wxapp['id'],
		);
		uni_setting('open_appid',$open_bind);
		return true;
	}
	public function bind_open($appid,$open_appid){
		$api_url='https://api.weixin.qq.com/cgi-bin/open/bind?access_token='.$this->wxapp['access_token'];
		
		$post=array(
			'appid'=>$appid,
			'open_appid'=>$open_appid,
		);
		$post=ijson_encode($post);
		$result=$this->request($api_url,$post);
		if($result['errcode']){
			
			exi('绑定失败：'.$result['errcode'].$result['errmsg'],'error');
		}
		return true;
	}
	/*
		创建小程序接口
	*/
	public function add_wxapp($post){
		$api_url='https://api.weixin.qq.com/cgi-bin/component/fastregisterweapp?action=create&component_access_token='.$this->component_access_token;		
		$data=array(
			'name'=>$post['merch_name'],
			'code'=>$post['merch_code'],
			'code_type'=>$post['merch_code_type'],
			'legal_persona_wechat'=>$post['merch_legal_persona_wechat'],
			'legal_persona_name'=>$post['merch_legal_persona_name'],
			'component_phone'=>$post['merch_component_phone'],
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		查询创建任务状态
	*/
	public function search_addwxapp($post){
		$api_url='https://api.weixin.qq.com/cgi-bin/component/fastregisterweapp?action=search&component_access_token='.$this->component_access_token;		
		$data=array(
			'name'=>$post['merch_name'],
			'legal_persona_wechat'=>$post['merch_legal_persona_wechat'],
			'legal_persona_name'=>$post['merch_legal_persona_name'],
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		设置小程序名称
	*/
	public function set_wxapp_title($post){
		$api_url='https://api.weixin.qq.com/wxa/setnickname?access_token='.$this->component_access_token;		
		$data=array(
			'nick_name'=>trim($post['title']),
			'id_card'=>trim($post['merch_id_card']),
			'license'=>trim($post['merch_license']),
			'naming_other_stuff_1'=>$post['naming_other_stuff'][0],
			'naming_other_stuff_2'=>$post['naming_other_stuff'][1],
			'naming_other_stuff_3'=>$post['naming_other_stuff'][2],
			'naming_other_stuff_4'=>$post['naming_other_stuff'][3],
			'naming_other_stuff_5'=>$post['naming_other_stuff'][4],
			'naming_other_stuff_6'=>$post['naming_other_stuff'][5],
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		设置服务器域名
	*/
	public function set_wxapp_modify_domain($action='get',$post=array()){
		$api_url='https://api.weixin.qq.com/wxa/modify_domain?access_token='.$this->component_access_token.'&action='.$action;		
		$data=array(
			'requestdomain'=>trim($post['requestdomain']),
			'wsrequestdomain'=>trim($post['wsrequestdomain']),
			'uploaddomain'=>trim($post['uploaddomain']),
			'downloaddomain'=>trim($post['downloaddomain']),
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		设置业务域名
	*/
	public function set_wxapp_webviewdomain($action='get',$post=array()){
		$api_url='https://api.weixin.qq.com/wxa/setwebviewdomain?access_token='.$this->component_access_token.'&action='.$action;		
		$data=array(
			'webviewdomain'=>trim($post['webviewdomain']),
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		设置logo
	*/
	public function set_wxapp_logo($post=array()){
		$api_url='https://api.weixin.qq.com/cgi-bin/account/modifyheadimage?access_token='.$this->component_access_token;		
		$data=array(
			'head_img_media_id'=>trim($post['logo']),
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		设置desc
	*/
	public function set_wxapp_desc($post=array()){
		$api_url='https://api.weixin.qq.com/cgi-bin/account/modifysignature?access_token='.$this->component_access_token;		
		$data=array(
			'signature'=>trim($post['desc']),
		);
		$data=ijson_encode($data);
		$result=$this->request($api_url,$data);
		return $result;
	}
	/*
		执行接口请求
	*/
	private function request($url,$post){
		if(is_array($post)){
			$post=ijson_encode($post);
		}
		$result=cfc('http')->request($url,$post);
		$result=@json_decode($result,true);
		
		return $result;
	}
	
	//错误日志函数
	private function log_error($data,$title){
		$log=array();
		$log[]='*********************';
		$log[]=date('y/m/d H:i:s');
		$log[]='事件：'.$title;
		$log[]='关联小程序id：'.$this->wxapp['id'];
		$log[]='参数：';
		$log[]=var_export($data,true);
		$log=implode("\n",$log);
		file_put_contents(ROOT_AT.'error_logs/open_error.log',$log,FILE_APPEND);
	}
	//错误码
	public function error_code($code, $errmsg = '未知错误') {//获取错误详情
		global $_AR;
		$errors = array(
			'-1' => '非法 action 参数',
			'0' => '请求成功',
			'89247' => '内部错误',
			'89250' => '未找到该任务',
			'89251' => '模板消息已下发，待法人人脸核身校验',
			'89252' => '法人&企业信息一致性校验中',
			'89253' => '缺少参数',
		);
		$code = strval($code);
		if($errors[$code]) {
			return $errors[$code];
		} else {
			return $errmsg;
		}
	}
}
?>